﻿﻿using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
﻿using System.Windows.Input;
﻿using Microsoft.Win32;
﻿using SearchInFiles.Properties;

namespace SearchInFiles
{
    internal class Message : TextBlock
    {
        private MatchType MatchType { get; set; }
        private string Path { get; set; }
        private int? LineNumber { get; set; }
        private static readonly string NotepadPpExeFilePath;

        private const string NOTEPAD_PP_EXE_REGISTRY_PATH =
            "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\notepad++.exe";

        private const string NOTEPAD_EXE_FILE_PATH =
            "notepad.exe";

        private const string NOTEPAD_PP_COMMAND_LINE_ARGUMENTS =
            "\"{0}\" -n{1}";

        public Action OpenDefault;

        static Message()
        {
            try
            {
                NotepadPpExeFilePath = (string) Registry.GetValue(NOTEPAD_PP_EXE_REGISTRY_PATH, null, null);
            }
            catch
            {
            }
        }

        public Message(string path, int? lineNumber, string text, string toolTip, MatchType matchType)
        {
            Text = text;
            LineNumber = lineNumber;
            Path = path;
            ToolTip = toolTip;
            MatchType = matchType;
            Cursor = Cursors.Hand;
            var cm = new ContextMenu();
            if (matchType == MatchType.FileName)
            {
                var openFile = new MenuItem {Header = GuiResources.OpenFile};
                var openFileWithNotepad = new MenuItem {Header = GuiResources.OpenFileWithNotepad};
                openFile.Click += OpenFile_Click;
                openFileWithNotepad.Click += OpenFileWithNotepad_Click;
                cm.Items.Add(openFile);
                cm.Items.Add(openFileWithNotepad);
                OpenDefault = OpenFile;
            }
            else
            {
                OpenDefault = OpenDirectory;
            }
            var openDirectory = new MenuItem {Header = GuiResources.OpenDirectory};
            cm.Items.Add(openDirectory);
            openDirectory.Click += OpenDirectory_Click;
            ((MenuItem) cm.Items[0]).FontWeight = FontWeights.Bold;
            ContextMenu = cm;
        }

        private void OpenFileWithNotepad_Click(object sender, RoutedEventArgs e)
        {
            OpenFileWithNotepad();
        }

        private void OpenFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFile();
        }

        private void OpenDirectory_Click(object sender, RoutedEventArgs e)
        {
            OpenDirectory();
        }

        private void OpenFile()
        {
            string appName;
            Utilities.GetRegisteredApplication(System.IO.Path.GetExtension(Path), out appName);
            if (appName != null && appName.Contains("devenv") && LineNumber.HasValue)
            {
                if (!Utilities.OpenWithVisualStudio(Path, LineNumber.Value + 1))
                {
                    StartProcess("devenv",
                                 string.Format("/edit {0} /command \"edit.goto {1}\"", Path, LineNumber + 1));
                }
            }
            else
            {
                StartProcess(Path);
            }
        }

        private void OpenFileWithNotepad()
        {
            if (NotepadPpExeFilePath != null)
            {
                var args = LineNumber.HasValue
                               ? String.Format(NOTEPAD_PP_COMMAND_LINE_ARGUMENTS, Path, LineNumber + 1)
                               : Path;
                StartProcess(NotepadPpExeFilePath, args);
            }
            else
            {
                StartProcess(NOTEPAD_EXE_FILE_PATH, Path);
            }
        }

        private void OpenDirectory()
        {
            var directory = MatchType == MatchType.FileName ? System.IO.Path.GetDirectoryName(Path) : Path;
            if (directory != null)
            {
                StartProcess(directory);
            }
        }

        private static void StartProcess(string path, string args = null)
        {
            try
            {
                Process.Start(path, args);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ErrorResources.ErrorOpeningFile + ex.Message);
            }
        }
    }
}